#include "GLRegisterUsersScene.h"

#include <iostream>
#include <sstream>

#include "GLSceneOrthogonalMode.h"
#include "GLSceneInterfaceDrawers.h"
#include "Player.h"

namespace catan
{

GLRegisterUsersScene::GLRegisterUsersScene(GameState &gameState, SDLCanvas &sdlCanvas, GLTextures &glTextures, GameMap &gameMap): gameStateRef(&gameState), sdlCanvasRef(&sdlCanvas), glTexturesRef(&glTextures), gameMapRef(&gameMap), focused(0), frame(0)
{
	for (int i=0; i<4; ++i)
	{
		reds[i] = 0.0f;
		greens[i] = 0.0f;
		blues[i] = 0.0f;
	}
	reds[0] = 1.0f;
	blues[1] = 1.0f;
	greens[2] = 1.0f;
	reds[3] = greens[3] = 1.0f; 
}

void GLRegisterUsersScene::poll()
{
	SDL_Event *mouseButtonDownEvent = gameStateRef->pollMouseButtonDownEvent();
	if (mouseButtonDownEvent != NULL)
	{
		int x = mouseButtonDownEvent->button.x;
		int y = mouseButtonDownEvent->button.y;
		float xRatio = (sdlCanvasRef->getWindowUnitWidth() - sdlCanvasRef->getClientUnitWidth())/2;
		float yRatio = (sdlCanvasRef->getWindowUnitHeight() - sdlCanvasRef->getClientUnitHeight())/2;
		//float clientX = (x - xRatio*sdlCanvasRef->getWidth()*(sdlCanvasRef->getClientUnitWidth()/sdlCanvasRef->getWindowUnitWidth()))*(sdlCanvasRef->getWindowUnitWidth()/sdlCanvasRef->getWidth());
		//float clientY = (y - yRatio*sdlCanvasRef->getHeight()*(sdlCanvasRef->getClientUnitHeight()/sdlCanvasRef->getWindowUnitHeight()))*(sdlCanvasRef->getWindowUnitHeight()/sdlCanvasRef->getHeight());
		float clientX = x*sdlCanvasRef->getWindowUnitWidth()/sdlCanvasRef->getWidth() - xRatio*sdlCanvasRef->getClientUnitWidth();
		float clientY = y*sdlCanvasRef->getWindowUnitHeight()/sdlCanvasRef->getHeight() - yRatio*sdlCanvasRef->getClientUnitHeight();
		std::cout << clientX << ", " << clientY << std::endl;
		std::cout << x << ", " << xRatio << ", " << sdlCanvasRef->getWidth() << ", " << sdlCanvasRef->getWindowUnitWidth() << ", " << sdlCanvasRef->getWidth() << std::endl;
		int focusedCandidate = 20 * (clientY-0.55f*(3.0f/4));
		if (focusedCandidate >= 0 && focusedCandidate < gameStateRef->getNumberOfPlayers() && clientX > 0.4f)
		{
			focused = focusedCandidate;
		}
		int colorCandidate = 100 * (clientY-0.55f*(3.0f/4));
		if (clientX >= 0.2f && clientX <= 0.35f)
		{
			for (int i=0; i<gameStateRef->getNumberOfPlayers(); ++i)
			{
				if (colorCandidate == i*5)
				{
					reds[i] = (clientX - 0.2f)/0.15f;
				}
				else if (colorCandidate == i*5 + 1)
				{
					greens[i] = (clientX - 0.2f)/0.15f;
				}
				else if (colorCandidate == i*5 + 2)
				{
					blues[i] = (clientX - 0.2f)/0.15f;
				}
			}
		}
		if (clientX >= 0.4f && clientX <= 0.6f && clientY >= 0.65f && clientY <= 0.7f)
		{
			bool enabledOKButton = true;
			for (int i=0; i < gameStateRef->getNumberOfPlayers(); ++i)
			{
				for (int j=i+1; j < gameStateRef->getNumberOfPlayers(); ++j)
				{
					enabledOKButton = enabledOKButton && usernames[i] != usernames[j];
				}
				enabledOKButton = enabledOKButton && usernames[i].length() > 0;
				enabledOKButton = enabledOKButton && (reds[i] >= 0.5f || greens[i] >= 0.5f || blues[i] >= 0.5f);
			}
			if (enabledOKButton)
			{
				GLSceneInterfaceDrawers::drawRectangularTexture(0.4f, 0.6f, 0.70f, 0.65f, (enabledOKButton ? glTexturesRef->getOKButtonTexture() : glTexturesRef->getOKButtonDisabledTexture()), *sdlCanvasRef);
				for (int i=0; i<gameStateRef->getNumberOfPlayers(); ++i)
				{
					Player player = Player(usernames[i], reds[i], greens[i], blues[i]);
					gameStateRef->addPlayer(player);
					#ifdef Claudiu			//add a harbor manually; this code doesn't affect the game execution as far I Know
						/*if (i == 0){
							player.addSettlement(SiteCoordinate(x3,y5,horizontalCL));			//adds a harbor
							std::cout << "ADDED a settlement" << std::endl;
						}
						*/
					#endif
				}

				gameStateRef->nextScreen();
			}
		}
	}
	SDL_Event *keyDownEvent = gameStateRef->pollKeyDownEvent();
	if (keyDownEvent != NULL)
	{
		if (keyDownEvent->key.keysym.sym == SDLK_BACKSPACE)
		{
			usernames[focused] = usernames[focused].substr(0, (usernames[focused].length() > 0 ? usernames[focused].length() - 1 : 0));
		}
		else if (((SDL_GetModState() & KMOD_SHIFT) == 0 && keyDownEvent->key.keysym.sym == SDLK_TAB) || keyDownEvent->key.keysym.sym == SDLK_DOWN)
		{
			focused = (focused + 1) % gameStateRef->getNumberOfPlayers();
		}
		else if (((SDL_GetModState() & KMOD_SHIFT) != 0 && keyDownEvent->key.keysym.sym == SDLK_TAB) || keyDownEvent->key.keysym.sym == SDLK_UP)
		{
			focused = (focused + gameStateRef->getNumberOfPlayers() - 1) % gameStateRef->getNumberOfPlayers();
		}
		else
		{
			if ((keyDownEvent->key.keysym.unicode & 0xFF80) == 0)
			{
				char typedCharacter = static_cast<char>(keyDownEvent->key.keysym.unicode & 0x7F);
				if (typedCharacter >= 32 && typedCharacter < 127 && usernames[focused].length() < 16)
				{
					usernames[focused] += typedCharacter;
				}
			}
		}
	}
}

void GLRegisterUsersScene::draw()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	GLSceneOrthogonalMode::begin(*sdlCanvasRef);
		GLSceneInterfaceDrawers::drawRectangularTexture(0.2f, 0.8f, 0.175f + 0.6f/3, 0.175f, glTexturesRef->getLogoTexture(), *sdlCanvasRef);
		GLfloat oldColor[4];
		glGetFloatv(GL_CURRENT_COLOR, oldColor);
		for (int i=0; i<gameStateRef->getNumberOfPlayers(); ++i)
		{
			std::ostringstream outputStream;
			outputStream << "Player " << (i+1) << ": ";
			std::string output = outputStream.str();
			bool drawCursor = ((frame/10)%2==0 && focused == i);
			GLSceneInterfaceDrawers::drawText(output.c_str(), output.length(), false, 0.55f*(3.0f/4) + 0.05f*i, 0.4f, 0.03f, glTexturesRef->getTextWithBlackBackgroundTexture(), *sdlCanvasRef);
			glColor3f(reds[i], greens[i], blues[i]);
			GLSceneInterfaceDrawers::drawText(usernames[i].c_str(), usernames[i].length(), drawCursor, 0.55f*(3.0f/4) + 0.05f*i, 0.4f+(0.03f*(32.0f/66)*output.length()), 0.03f, glTexturesRef->getTextWithBlackBackgroundTexture(), *sdlCanvasRef);
			glBegin(GL_QUADS);
				glColor3f(1.0f, greens[i], blues[i]);
				glVertex3f(0.35f, 0.55f*(3.0f/4) + 0.05f*i, 0.0f);
			    
				glColor3f(0.0f, greens[i], blues[i]);
				glVertex3f(0.2f, 0.55f*(3.0f/4) + 0.05f*i, 0.0f);
			    
				glVertex3f(0.2f, 0.55f*(3.0f/4) + 0.05f*i + 0.01f, 0.0f);

				glColor3f(1.0f, greens[i], blues[i]);
				glVertex3f(0.35f, 0.55f*(3.0f/4) + 0.05f*i + 0.01f, 0.0f);

				glColor3f(reds[i], 1.0f, blues[i]);
				glVertex3f(0.35f, 0.55f*(3.0f/4) + 0.05f*i + 0.01, 0.0f);
			    
				glColor3f(reds[i], 0.0f, blues[i]);
				glVertex3f(0.2f, 0.55f*(3.0f/4) + 0.05f*i + 0.01f, 0.0f);
			    
				glVertex3f(0.2f, 0.55f*(3.0f/4) + 0.05f*i + 0.02f, 0.0f);

				glColor3f(reds[i], 1.0f, blues[i]);
				glVertex3f(0.35f, 0.55f*(3.0f/4) + 0.05f*i + 0.02f, 0.0f);

				glColor3f(reds[i], greens[i], 1.0f);
				glVertex3f(0.35f, 0.55f*(3.0f/4) + 0.05f*i + 0.02, 0.0f);
			    
				glColor3f(reds[i], greens[i], 0.0f);
				glVertex3f(0.2f, 0.55f*(3.0f/4) + 0.05f*i + 0.02f, 0.0f);
			    
				glVertex3f(0.2f, 0.55f*(3.0f/4) + 0.05f*i + 0.03f, 0.0f);

				glColor3f(reds[i], greens[i], 1.0f);
				glVertex3f(0.35f, 0.55f*(3.0f/4) + 0.05f*i + 0.03f, 0.0f);
				
				glColor3f(reds[i], greens[i], blues[i]);
				glVertex3f(0.385f, 0.55f*(3.0f/4) + 0.05f*i + 0.005f, 0.0f);
				glVertex3f(0.365f, 0.55f*(3.0f/4) + 0.05f*i + 0.005f, 0.0f);
				glVertex3f(0.365f, 0.55f*(3.0f/4) + 0.05f*i + 0.025f, 0.0f);
				glVertex3f(0.385f, 0.55f*(3.0f/4) + 0.05f*i + 0.025f, 0.0f);
			glEnd();
			glColor3f(1.0f, 1.0f, 1.0f);
			glBegin(GL_LINE_LOOP);
				glVertex3f(0.39f, 0.55f*(3.0f/4) + 0.05f*i, 0.0f);
				glVertex3f(0.36f, 0.55f*(3.0f/4) + 0.05f*i, 0.0f);
				glVertex3f(0.36f, 0.55f*(3.0f/4) + 0.05f*i + 0.03f, 0.0f);
				glVertex3f(0.39f, 0.55f*(3.0f/4) + 0.05f*i + 0.03f, 0.0f);
			glEnd();
		}
	    glClear(GL_DEPTH_BUFFER_BIT);
		for (int i=0; i<gameStateRef->getNumberOfPlayers(); ++i)
		{
			GLfloat oldLineWidth;
			glGetFloatv(GL_LINE_WIDTH, &oldLineWidth);
			glLineWidth(3.0f);
			glBegin(GL_LINES);
				glColor3f(1.0f, 0.0f, 0.0f);
				glVertex3f(0.2f + 0.15f*reds[i], 0.55f*(3.0f/4) + 0.05f*i, 0.0f);
				glVertex3f(0.2f + 0.15f*reds[i], 0.55f*(3.0f/4) + 0.05f*i + 0.01f, 0.0f);
			    
				glColor3f(0.0f, 1.0f, 0.0f);
				glVertex3f(0.2f + 0.15f*greens[i], 0.55f*(3.0f/4) + 0.05f*i + 0.01f, 0.0f);
				glVertex3f(0.2f + 0.15f*greens[i], 0.55f*(3.0f/4) + 0.05f*i + 0.02f, 0.0f);
			    
				glColor3f(0.0f, 0.0f, 1.0f);
				glVertex3f(0.2f + 0.15f*blues[i], 0.55f*(3.0f/4) + 0.05f*i + 0.02f, 0.0f);
				glVertex3f(0.2f + 0.15f*blues[i], 0.55f*(3.0f/4) + 0.05f*i + 0.03f, 0.0f);
			glEnd();
			glLineWidth(oldLineWidth);
		}
		glColor3f(oldColor[0], oldColor[1], oldColor[2]);
		bool enabledOKButton = true;
		for (int i=0; i < gameStateRef->getNumberOfPlayers(); ++i)
		{
			for (int j=i+1; j < gameStateRef->getNumberOfPlayers(); ++j)
			{
				enabledOKButton = enabledOKButton && usernames[i] != usernames[j];
			}
			enabledOKButton = enabledOKButton && usernames[i].length() > 0;
			enabledOKButton = enabledOKButton && (reds[i] >= 0.5f || greens[i] >= 0.5f || blues[i] >= 0.5f);
		}
		GLSceneInterfaceDrawers::drawRectangularTexture(0.4f, 0.6f, 0.70f, 0.65f, (enabledOKButton ? glTexturesRef->getOKButtonTexture() : glTexturesRef->getOKButtonDisabledTexture()), *sdlCanvasRef);
	GLSceneOrthogonalMode::end();
    SDL_GL_SwapBuffers();
    if (timer.secondsSinceReference() > 1.0f/25)
    {
    	frame++;
    	timer.resetReference();
    }
}

}
